home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 …ember: Reference Library / Dev.CD Dec 00 RL Disk 1.toast / pc / technical documentation / develop / develop issue 28 / develop issue 28 code / merge tools / undifference.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-31  |  25.3 KB  |  647 lines

  1. /* Undifference utility for Eclectus integration utilities.
  2.      Copyright (C) 1992-1996 Eclectus (D. John Anderson, Alan B. Harper).
  3.  
  4. This file is part of the Eclectus integration utilities.
  5.  
  6. Eclectus integration utilities are free software; you can redistribute
  7. it and/or modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 1, or
  9. (at your option) any later version.
  10.  
  11. Eclectus integration utilities is distributed in the hope that it
  12. will be useful, but WITHOUT ANY WARRANTY; without even the implied
  13. warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. See the GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with the Eclectus integration utilities; see the file COPYING.
  18. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
  19. MA 02139, USA.    */
  20.  
  21. #include "diff.h"
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <limits.h>
  25. #ifdef DF_MACHINE_MACINTOSH
  26.     #include <CursorCtl.h>
  27. #endif
  28.  
  29. static int                            lockCreatedFiles = FALSE;
  30. static const char          *programNamePtr;
  31.  
  32. static unsigned hashValue;
  33.  
  34. void                        CommandLine (int argc, const char **argv,
  35.                                                          const char **oldPathNamePtrPtr,
  36.                                                          const char **pathScriptNamePtrPtr,
  37.                                                          const char **newPathNamePtrPtr);
  38. void                        CommandLineError (int errorMessage, const char *theString);
  39. int __cdecl            main (int argc, const char **argv);
  40. void                        UnDiffPaths (const char *oldPathNamePtr, const char *pathScriptNamePtr, const char *newPathNamePtr);
  41.     void                        AppendFileSuffixToPaths (char *oldPathNamePtr,    char *newPathNamePtr, FILE *scriptFilePtr);
  42.     void                        CopyLines (register FILE *oldFilePtr,
  43.                                                          register FILE *newFilePtr,
  44.                                                          register int lineCount,
  45.                                                          int excludeLastReturn);
  46.     int                         ReadInt (register FILE *filePtr);
  47.  
  48. void
  49. CommandLine (int argc, const char **argv,
  50.                          const char **oldPathNamePtrPtr,
  51.                          const char **pathScriptNamePtrPtr,
  52.                          const char **newPathNamePtrPtr)
  53. /*
  54.  * Parses the command line.  Fills out the data pointed to by oldPathNamePtrPtr,
  55.  * pathScriptNamePtrPtr and newPathNamePtrPtr.
  56.  */
  57. {
  58.     char                                    commandChar;
  59.     register const char  *commandStringPtr;
  60.     int                                     fileCount;
  61.  
  62.     fileCount = 0;
  63.  
  64.     programNamePtr = *argv++;
  65.     argc--;
  66.  
  67. /* Parse the commands and make sure they are legal */
  68.  
  69.     while (argc > 0) {
  70.         commandStringPtr = *argv++;
  71.         argc--;
  72.         if (*commandStringPtr != '-') {
  73.  
  74.             switch (fileCount) {
  75.                 case (0):
  76.                     *oldPathNamePtrPtr = commandStringPtr;
  77.                     break;
  78.                 case (1):
  79.                     *pathScriptNamePtrPtr = commandStringPtr;
  80.                     break;
  81.                 case (2):
  82.                     *newPathNamePtrPtr = commandStringPtr;
  83.                     break;
  84.                 default:
  85.                     CommandLineError (THREE_UN_DIFFERENCE_FILES, NULL);
  86.                     break;
  87.             }
  88.             fileCount ++;
  89.         } else {
  90.             if (strlen (commandStringPtr) != 2)
  91.                 CommandLineError (UNEXPECTED_OPTION, commandStringPtr);
  92.             commandChar = *(commandStringPtr + 1);
  93.             switch (commandChar) {
  94.                     case ('l'):
  95.                         lockCreatedFiles = TRUE;
  96.                         break;
  97.                 #ifdef DF_DEBUG
  98.                     case ('X'):
  99.                         ECCheckFreedBlocks = 1;
  100.                         break;
  101.                     case ('x'):
  102.                         ECHeapCheckOn = 1;
  103.                         break;
  104.                 #endif
  105.                 default:
  106.                     CommandLineError (UNEXPECTED_OPTION, commandStringPtr);
  107.                     break;
  108.             }
  109.         }
  110.     }
  111.     if (fileCount != 3)
  112.         CommandLineError (THREE_UN_DIFFERENCE_FILES, NULL);
  113. }
  114.  
  115.     void
  116.     CommandLineError (int errorMessage, const char *theString)
  117.     /*
  118.      * Part of CommandLine.
  119.      */
  120.     {
  121.         fprintf (stderr, "# - ");
  122.         if (theString != NULL)
  123.             fprintf (stderr, ECMessagessArray [errorMessage], theString);
  124.         else
  125.             fprintf (stderr, ECMessagessArray [errorMessage], "");
  126.         fprintf (stderr, ".\n\n"
  127.                                          "### UnDifference version %s\n"
  128.                                          "#usage: %s [-l] SourcePath DifferenceScriptFile DestinationPath\n"
  129.                                    "        -l locks all files in the destination\n\n",
  130.                                          VERSION_STRING,
  131.                                           programNamePtr);
  132.         exit (EXIT_FAILURE);
  133.     }
  134.  
  135. int
  136. __cdecl main (int argc, const char **argv)
  137. {
  138.     #ifdef DF_DEBUG
  139.         ECUns32        allocatedBytes;
  140.     #endif
  141.     const char *oldPathNamePtr;
  142.     const char *newPathNamePtr;
  143.     const char *pathScriptNamePtr;
  144.  
  145.     CommandLine (argc, argv, &oldPathNamePtr, &pathScriptNamePtr, &newPathNamePtr);
  146.     UnDiffPaths (oldPathNamePtr, pathScriptNamePtr, newPathNamePtr);
  147.  
  148.     #ifdef DF_DEBUG
  149.         allocatedBytes = ECDebugPrintMemoryUsage (stderr);
  150.         if (allocatedBytes != 0) {
  151.             fprintf (stderr, "\n\n"
  152.                                              "MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!\n"
  153.                                              "MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!\n"
  154.                                              "MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!\n"
  155.                                              "MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!\n"
  156.                                              "MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!  MEMORY LEAK!\n"
  157.                                              "\n\n");
  158.         }
  159.     #endif
  160.     return (0);
  161. }
  162.  
  163. void
  164. UnDiffPaths (const char *oldPathNamePtr, const char *pathScriptNamePtr, const char *newPathNamePtr)
  165. {
  166.     static const char FirstCommandSet[] = {
  167.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* nul..bel */
  168.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* bs..si */
  169.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* dle..etb */
  170.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* can..us */
  171.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* space..' */
  172.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* (../ */
  173.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 0..7 */
  174.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 8..? */
  175.         FALSE, TRUE,    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* @..G */
  176.         TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* H..O */
  177.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* P..W */
  178.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* X.._ */
  179.         FALSE, TRUE,    TRUE,  FALSE, TRUE,  FALSE, TRUE,  FALSE, /* `..g */
  180.         TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* h..o */
  181.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* p..w */
  182.         TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* x..DEL */
  183.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  184.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  185.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  186.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  187.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  188.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  189.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  190.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  191.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  192.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  193.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  194.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  195.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  196.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  197.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  198.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  199.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  200.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE    /* Non ASCII */
  201.     };
  202.  
  203.     static const char DoneWithFileSet[] = {
  204.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* nul..bel */
  205.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* bs..si */
  206.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* dle..etb */
  207.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* can..us */
  208.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* space..' */
  209.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* (../ */
  210.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 0..7 */
  211.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 8..? */
  212.         FALSE, FALSE,    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* @..G */
  213.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* H..O */
  214.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* P..W */
  215.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* X.._ */
  216.         FALSE, FALSE,    TRUE,  FALSE, TRUE,  FALSE, TRUE,  FALSE, /* `..g */
  217.         TRUE,  FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* h..o */
  218.         FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  FALSE, FALSE, /* p..w */
  219.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* x..DEL */
  220.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  221.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  222.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  223.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  224.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  225.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  226.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  227.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  228.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  229.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  230.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  231.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  232.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  233.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  234.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  235.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  236.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  237.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE    /* Non ASCII */
  238.     };
  239.  
  240.     static const char FileOrDirectorySet[] = {
  241.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* nul..bel */
  242.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* bs..si */
  243.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* dle..etb */
  244.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* can..us */
  245.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* space..' */
  246.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* (../ */
  247.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 0..7 */
  248.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 8..? */
  249.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* @..G */
  250.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* H..O */
  251.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* P..W */
  252.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* X.._ */
  253.         FALSE, FALSE, TRUE,  FALSE, TRUE,  FALSE, TRUE,  FALSE, /* `..g */
  254.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* h..o */
  255.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,    FALSE, FALSE, /* p..w */
  256.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* x..DEL */
  257.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  258.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  259.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  260.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  261.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  262.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  263.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  264.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  265.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  266.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  267.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  268.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  269.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  270.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  271.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  272.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  273.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  274.         FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE    /* Non ASCII */
  275.     };
  276.  
  277.     int                                        binaryFile;
  278.     int                                     commandCharThatIsReallyAnInt;
  279.     int                                        fileAttributes;
  280.     int                                     firstPass;
  281.     unsigned                             hashRead;
  282.     register unsigned int    hexCharThatIsReallyAnInt;
  283.     register int                    highHexDigit;
  284.     int                                     ioResult;
  285.     int                                     lineCount;
  286.     FILE                                 *newFilePtr;
  287.     char                                    newPathName [FILENAME_MAX + 1];
  288.     int                                     numberRead;
  289.     FILE                                 *oldFilePtr;
  290.     int                                        oldFileType;
  291.     int                                     oldLineNumber;
  292.     char                                    oldPathName [FILENAME_MAX + 1];
  293.     FILE                                 *scriptFilePtr;
  294.     int                                     sourceLines;
  295.     char                                    startScriptBuffer [sizeof (DIFFERENCE_SCRIPT_START_STRING)];
  296.     int                                     charThatIsReallyAnUnsInt;
  297.  
  298.     binaryFile = FALSE;
  299.     hashValue = 0;
  300.     newFilePtr = NULL;
  301.     oldFilePtr = NULL;
  302.     firstPass = TRUE;
  303.     oldLineNumber = 1;
  304.     newPathName [0] = '\0';
  305.     fileAttributes = 0;
  306.     AppendStringToPathName (newPathName, newPathNamePtr);
  307.     oldPathName [0] = '\0';
  308.     AppendStringToPathName (oldPathName, oldPathNamePtr);
  309.  
  310.     if (FileType (oldPathNamePtr) == BAD_FILE_TYPE)
  311.         ErrorWithStringArgument (CANT_OPEN_FILE, oldPathNamePtr);
  312.  
  313.     scriptFilePtr = fopen (pathScriptNamePtr, "r");
  314.     if (scriptFilePtr == NULL)
  315.         ErrorWithStringArgument (CANT_OPEN_FILE, pathScriptNamePtr);
  316.  
  317.     numberRead = fread (startScriptBuffer, sizeof (char), sizeof (startScriptBuffer) - 1, scriptFilePtr);
  318.     if (numberRead != sizeof (startScriptBuffer) - 1 ||
  319.             memcmp (startScriptBuffer, DIFFERENCE_SCRIPT_START_STRING, sizeof (startScriptBuffer) - 1) != 0)
  320.         Error (BAD_SCRIPT_FORMAT);
  321.  
  322.     do {
  323.         commandCharThatIsReallyAnInt = getc (scriptFilePtr);
  324.         if (firstPass) {
  325.             if (FirstCommandSet [commandCharThatIsReallyAnInt]) {
  326.                 if (FileOrDirectorySet [commandCharThatIsReallyAnInt]) {
  327.                     ioResult = MakeDirectory (newPathName);
  328.                     if (ioResult != 0)
  329.                         ErrorWithStringArgument (CANT_CREATE_DIRECTORY, newPathName);
  330.                 } else {
  331.                     oldFilePtr = fopen (oldPathName, "r");
  332.                     if (oldFilePtr == NULL)
  333.                         ErrorWithStringArgument (CANT_OPEN_FILE, oldPathName);
  334.                     oldFileType = FileType (oldPathName);
  335.                     binaryFile = oldFileType == BINARY_TYPE; 
  336.                     newFilePtr = CreateTypedFile (newPathName, binaryFile);
  337.                     fileAttributes = RESOURCE_MASK;
  338.                 }
  339.                 firstPass = FALSE;
  340.             }
  341.         }
  342.         if (newFilePtr != NULL && DoneWithFileSet [commandCharThatIsReallyAnInt]) {
  343.             if (oldFilePtr != NULL) {
  344.                 if (oldLineNumber == 1)
  345.                     fileAttributes |= DATE_MASK;
  346.                 if (binaryFile) {
  347.                     goto BinaryCopy;
  348.                     do {
  349.                         hashValue = HASH (hashValue, charThatIsReallyAnUnsInt);
  350.                         putc (charThatIsReallyAnUnsInt, newFilePtr);    
  351. BinaryCopy:    charThatIsReallyAnUnsInt = (unsigned int) getc (oldFilePtr);
  352.                     } while (charThatIsReallyAnUnsInt != EOF);
  353.                 } else {
  354.                     CopyLines (oldFilePtr, newFilePtr, INT_MAX, /*exclude last return is */ FALSE);
  355.                 }
  356.                 if (fclose (oldFilePtr) != 0)
  357.                     Error (UNEXPECTED_IO_ERROR);
  358.                 oldFilePtr = NULL;
  359.             }
  360.             if (newFilePtr != NULL) {
  361.                 if (fclose (newFilePtr) != 0)
  362.                     Error (UNEXPECTED_IO_ERROR);
  363.                 newFilePtr = NULL;
  364.                 if (lockCreatedFiles)
  365.                     fileAttributes |= LOCK_MASK;
  366.                 CopyFileAttributes (oldPathName, newPathName, fileAttributes);
  367.                 RemoveNameSuffix (newPathName);
  368.                 RemoveNameSuffix (oldPathName);
  369.             }
  370.             oldLineNumber = 1;
  371.         }
  372.         switch (commandCharThatIsReallyAnInt) {
  373.             case (EOF):
  374.                 goto ExitLoop;
  375.             case ('#'): /* comment */
  376.                 do {
  377.                     charThatIsReallyAnUnsInt = (unsigned int) getc (scriptFilePtr);
  378.                     if (charThatIsReallyAnUnsInt == EOF)
  379.                         goto ExitLoop;
  380.                 } while (charThatIsReallyAnUnsInt != '\n');
  381.                 break;
  382.             case ('A'): /* Add lines without the last return */
  383.             case ('a'): /* Add lines without with the last return */
  384.                 if (newFilePtr == NULL)
  385.                     Error (BAD_SCRIPT_FORMAT);
  386.                 sourceLines = ReadInt (scriptFilePtr);
  387.                 lineCount = ReadInt (scriptFilePtr);
  388.                 sourceLines -= oldLineNumber - 1;
  389.                 CopyLines (oldFilePtr, newFilePtr, sourceLines, /*exclude last return is */ FALSE);
  390.                 oldLineNumber += sourceLines;
  391.                 CopyLines (scriptFilePtr,
  392.                                      newFilePtr,
  393.                                      lineCount,
  394.                                      /*exclude last return is */ commandCharThatIsReallyAnInt == 'A');
  395.                 break;
  396.             case ('b'): /* binary file */
  397.                 AppendFileSuffixToPaths (oldPathName, newPathName, scriptFilePtr);
  398.                 fprintf (stdout, "%s", newPathName);
  399.                 newFilePtr = CreateTypedFile (newPathName, /* binary is */ TRUE);
  400.                 oldFilePtr = fopen (oldPathName, "rb");
  401.                 fileAttributes = RESOURCE_MASK;
  402.                 binaryFile = TRUE;
  403.                 break;
  404.             case ('d'): /* directory */
  405.                 AppendFileSuffixToPaths (oldPathName, newPathName, scriptFilePtr);
  406.                 ioResult = MakeDirectory (newPathName);
  407.                 if (ioResult != 0)
  408.                     ErrorWithStringArgument (CANT_CREATE_DIRECTORY, newPathName);
  409.                 break;
  410.             case ('f'): /* ASCII file */
  411.                 AppendFileSuffixToPaths (oldPathName, newPathName, scriptFilePtr);
  412.                 fprintf (stdout, "%s", newPathName);
  413.                 newFilePtr = CreateTypedFile (newPathName, /* binary is */ FALSE);
  414.                 oldFilePtr = fopen (oldPathName, "r");
  415.                 fileAttributes = RESOURCE_MASK;
  416.                 binaryFile = FALSE;
  417.                 break;
  418.             case ('H'): /* hexidecimal data */
  419.                 if (!binaryFile)
  420.                     Error (BAD_SCRIPT_FORMAT);
  421.                 highHexDigit = FALSE;
  422.                 lineCount = ReadInt (scriptFilePtr);
  423.                 while (lineCount > 0) {
  424.                     do {
  425.                         charThatIsReallyAnUnsInt = (unsigned int) getc (scriptFilePtr);
  426.                         if (charThatIsReallyAnUnsInt == EOF)
  427.                             Error (BAD_SCRIPT_FORMAT);
  428.                         if (charThatIsReallyAnUnsInt == '\n')
  429.                             break;
  430.                         if (charThatIsReallyAnUnsInt >= '0' && charThatIsReallyAnUnsInt <= '9') {
  431.                             charThatIsReallyAnUnsInt -= '0';
  432.                             goto IsHex;
  433.                         }
  434.                         if (charThatIsReallyAnUnsInt >= 'A' && charThatIsReallyAnUnsInt <= 'F') {
  435.                             charThatIsReallyAnUnsInt += -'A' + 10;
  436. IsHex:                if (highHexDigit) {
  437.                                 hexCharThatIsReallyAnInt += charThatIsReallyAnUnsInt;
  438.                                 putc (hexCharThatIsReallyAnInt, newFilePtr);
  439.                                 hashValue = HASH (hashValue, hexCharThatIsReallyAnInt);
  440.                             } else {
  441.                                 hexCharThatIsReallyAnInt = charThatIsReallyAnUnsInt << 4;
  442.                             }
  443.                             highHexDigit = !highHexDigit;
  444.                         }
  445.                     } while (TRUE);
  446.                     lineCount--;
  447.                 }
  448.                 if (highHexDigit) /* We end with a nibble remaining in binary mode */
  449.                     Error (BAD_SCRIPT_FORMAT);
  450.                 /*
  451.                  * Set oldLineNumber to a value that indicates we have a new version of the file.  Also
  452.                  * seek to the end of the file so we won't copy any contents from the old file.
  453.                  */
  454.                 oldLineNumber = 2;
  455.                 if (oldFilePtr != NULL) {
  456.                     ioResult = fseek (oldFilePtr, 0, SEEK_END);
  457.                     if (ioResult != 0)
  458.                         ErrorWithStringArgument (UNEXPECTED_IO_ERROR, oldPathName);
  459.                 }
  460.                 break;
  461.             case ('h'): /* hash */
  462.                 hashRead = ReadInt (scriptFilePtr);
  463.                 if (hashRead != hashValue)
  464.                     fprintf (stdout, " %s", ECMessagessArray[HASH_DOESNT_MATCH]);
  465.                 putc ('\n', stdout);
  466.                 hashValue = 0;
  467.                 break;
  468.             case ('u'): /* up directory */        
  469.                 charThatIsReallyAnUnsInt = (unsigned int) getc (scriptFilePtr);
  470.                 if (charThatIsReallyAnUnsInt != '\n')
  471.                     Error (BAD_SCRIPT_FORMAT);
  472.                 RemoveNameSuffix (newPathName);
  473.                 RemoveNameSuffix (oldPathName);
  474.                 break;
  475.             case ('x'): /* delete lines */
  476.                 if (newFilePtr == NULL)
  477.                     Error (BAD_SCRIPT_FORMAT);
  478.                 sourceLines = ReadInt (scriptFilePtr);
  479.                 lineCount = ReadInt (scriptFilePtr);
  480.                 sourceLines -= oldLineNumber;
  481.                 CopyLines (oldFilePtr, newFilePtr, sourceLines, /*exclude last return is */ FALSE);
  482.                 oldLineNumber += sourceLines;
  483.                 CopyLines (oldFilePtr, NULL, lineCount, /*exclude last return is */ FALSE);
  484.                 oldLineNumber += lineCount;
  485.                 break;
  486.             default:
  487.                 Error (BAD_SCRIPT_FORMAT);
  488.                 break;
  489.         }
  490.     } while (TRUE);
  491.  
  492. ExitLoop:;
  493.     if (oldFilePtr != NULL || newFilePtr != NULL)
  494.         Error (BAD_SCRIPT_FORMAT);
  495. }
  496.  
  497.     void
  498.     AppendFileSuffixToPaths (char *oldPathNamePtr,    char *newPathNamePtr, FILE *scriptFilePtr)
  499.     {
  500.         register char     *charPtr;
  501.         unsigned int         charThatIsReallyAnUnsInt;
  502.         int                         length;
  503.         char                        suffix [FILENAME_MAX + 1];
  504.         char                     *suffixPtr;
  505.  
  506.         suffixPtr = suffix;
  507.         length = 0;
  508.         goto GetNameChar;
  509.         do {
  510.             *suffixPtr = (char) charThatIsReallyAnUnsInt;
  511.             if (length < FILENAME_MAX) {
  512.                 length ++;
  513.                 suffixPtr++;
  514.             }
  515. GetNameChar:
  516.             charThatIsReallyAnUnsInt = (unsigned int) getc (scriptFilePtr);
  517.         } while (charThatIsReallyAnUnsInt != '\n' && charThatIsReallyAnUnsInt != EOF);
  518.         *suffixPtr = '\0';
  519.  
  520.         charPtr = strrchr (oldPathNamePtr, DIRECTORY_CHAR);
  521.         if (charPtr == NULL || *(charPtr + 1) != '\0')
  522.             AppendCharToPathName (oldPathNamePtr, DIRECTORY_CHAR);
  523.         AppendStringToPathName (oldPathNamePtr, suffix);
  524.  
  525.         charPtr = strrchr (newPathNamePtr, DIRECTORY_CHAR);
  526.         if (charPtr == NULL || *(charPtr + 1) != '\0')
  527.             AppendCharToPathName (newPathNamePtr, DIRECTORY_CHAR);
  528.         AppendStringToPathName (newPathNamePtr, suffix);
  529.     }
  530.  
  531.     void
  532.     CopyLines (register FILE *oldFilePtr,
  533.                          register FILE *newFilePtr,
  534.                          register int lineCount,
  535.                          int excludeLastReturn)
  536.     {
  537.         register unsigned int    charThatIsReallyAnUnsInt;
  538.         int                                     copyUntilEOF;
  539.  
  540.         #ifdef DF_MACHINE_MACINTOSH
  541.             SpinCursor (1);
  542.         #endif
  543.         copyUntilEOF = lineCount == INT_MAX;
  544.         if (oldFilePtr != NULL) {
  545.             if (newFilePtr == NULL) {
  546.                 while (lineCount > 0) {
  547.                     do {
  548.                         charThatIsReallyAnUnsInt = (unsigned int) getc (oldFilePtr);
  549.                         if (charThatIsReallyAnUnsInt == EOF)
  550.                             goto EndOfFile;
  551.                     } while (charThatIsReallyAnUnsInt != '\n');
  552.                     lineCount --;
  553.                 }
  554.             } else {
  555.                 while (lineCount > 0) {
  556.                     goto GetChar1;
  557.                     do {
  558.                         putc (charThatIsReallyAnUnsInt, newFilePtr);
  559.                         hashValue = HASH (hashValue, charThatIsReallyAnUnsInt);
  560.     GetChar1: charThatIsReallyAnUnsInt = (unsigned int) getc (oldFilePtr);
  561.                         if (charThatIsReallyAnUnsInt == EOF)
  562.                             goto EndOfFile;
  563.                     } while (charThatIsReallyAnUnsInt != '\n');
  564.                     lineCount --;
  565.                     if (!excludeLastReturn || lineCount != 0) {
  566.                         putc (charThatIsReallyAnUnsInt, newFilePtr);
  567.                         /*
  568.                          * Use a machine independent value for '\n' since if is different on Mac, Windows and Next.
  569.                          */
  570.                         hashValue = HASH (hashValue, 13);
  571.                     }
  572.                 }
  573.             }
  574.         }
  575.  
  576.     EndOfFile:
  577.         if (lineCount != 0 && /* Lines processed doesn't match expected */
  578.                 !copyUntilEOF && /* Don't know exact number of lines */
  579.                 !(lineCount == 1 && newFilePtr == NULL) /* Source file doesn't end in return so it's off by one */)
  580.                 Error (BAD_SCRIPT_FOR_SOURCE);
  581.     }
  582.  
  583.     int
  584.     ReadInt (register FILE *filePtr)
  585.     /*
  586.      * scanf always seemed too complicated for it's own good.
  587.      */
  588.     {
  589.         #define MAX_STRING 24
  590.         int                         count;
  591.         unsigned int         charThatIsReallyAnUnsInt;
  592.         char                        string[MAX_STRING + 1];
  593.         register char  *stringPtr;
  594.  
  595.         static const char DigitAndMinus[] = {
  596.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* nul..bel */
  597.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* bs..si */
  598.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* dle..etb */
  599.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* can..us */
  600.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* space..' */
  601.             FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,    FALSE, FALSE, /* (../ */
  602.             TRUE,  TRUE,    TRUE,  TRUE,    TRUE,  TRUE,    TRUE,  TRUE,    /* 0..7 */
  603.             TRUE,  TRUE,    FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* 8..? */
  604.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* @..G */
  605.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* H..O */
  606.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* P..W */
  607.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* X.._ */
  608.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* `..g */
  609.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* h..o */
  610.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* p..w */
  611.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* x..DEL */
  612.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  613.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  614.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  615.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  616.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  617.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  618.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  619.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  620.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  621.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  622.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  623.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  624.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  625.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  626.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  627.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  628.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, /* Non ASCII */
  629.             FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE    /* Non ASCII */
  630.         };
  631.  
  632.         stringPtr = string;
  633.         count = MAX_STRING;
  634.         goto GetChar;
  635.         do {
  636.             *stringPtr++ = (char) charThatIsReallyAnUnsInt;
  637.             count --;
  638.     GetChar:
  639.             charThatIsReallyAnUnsInt = (unsigned int) getc (filePtr);
  640.         } while (DigitAndMinus [charThatIsReallyAnUnsInt] && count > 0);
  641.         if (count == 0)
  642.             Error (BAD_SCRIPT_FORMAT);
  643.         *stringPtr = '\0';
  644.         return (atoi (string));
  645.     }
  646.  
  647.